package com.ztesoft.web.baseconfig.service.impl;

import java.sql.Connection;
import java.sql.DatabaseMetaData;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.sql.DataSource;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.datasource.DataSourceUtils;
import org.springframework.stereotype.Service;

import com.ztesoft.core.common.Page;
import com.ztesoft.core.convert.IArgConversionService;
import com.ztesoft.core.db.ds.DynamicDataSourceManager;
import com.ztesoft.core.idproduce.ISequenceGenerator;
import com.ztesoft.framework.exception.BaseAppException;
import com.ztesoft.framework.log.ZTEsoftLogManager;
import com.ztesoft.framework.util.JsonUtil;
import com.ztesoft.framework.util.Utils;
import com.ztesoft.web.baseconfig.db.arg.DmSrcTableArg;
import com.ztesoft.web.baseconfig.db.arg.DmSrcTableArg.DmSrcTableCriteria;
import com.ztesoft.web.baseconfig.db.arg.DmStrategyDataobjRelArg;
import com.ztesoft.web.baseconfig.db.arg.DmStrategyDataobjRelArg.DmStrategyDataobjRelCriteria;
import com.ztesoft.web.baseconfig.db.dao.DmPlanDao;
import com.ztesoft.web.baseconfig.db.dao.DmPlanRelationDao;
import com.ztesoft.web.baseconfig.db.dao.DmSrcTableDao;
import com.ztesoft.web.baseconfig.db.dao.DmStrategyDao;
import com.ztesoft.web.baseconfig.db.dao.DmStrategyDataobjRelDao;
import com.ztesoft.web.baseconfig.db.dao.DmTableRelDao;
import com.ztesoft.web.baseconfig.db.dao.SubTableDefineDao;
import com.ztesoft.web.baseconfig.db.po.ColumnNamePO;
import com.ztesoft.web.baseconfig.db.po.DmSrcTablePO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyDataobjRelPO;
import com.ztesoft.web.baseconfig.db.po.DmStrategyPO;
import com.ztesoft.web.baseconfig.db.po.DmTableRelPO;
import com.ztesoft.web.baseconfig.db.po.DmTargetTablePO;
import com.ztesoft.web.baseconfig.db.po.SubTableDefinePO;
import com.ztesoft.web.baseconfig.db.po.SubTablePO;
import com.ztesoft.web.baseconfig.db.po.TableNamePO;
import com.ztesoft.web.baseconfig.service.IDmPlanRelationService;
import com.ztesoft.web.baseconfig.service.IDmPlanService;
import com.ztesoft.web.baseconfig.service.IDmSrcTableService;
import com.ztesoft.web.baseconfig.service.IDmStrategyDataobjRelService;
import com.ztesoft.web.baseconfig.service.IDmStrategyService;
import com.ztesoft.web.baseconfig.service.IDmTableRelService;
import com.ztesoft.web.baseconfig.service.ISubTableDefineService;
import com.ztesoft.web.common.DMSConstant;
import com.ztesoft.web.common.DMSConstant.Status;
import com.ztesoft.web.common.Util;
import com.ztesoft.web.common.db.arg.DmIndexInfoArg;
import com.ztesoft.web.common.db.arg.DmIndexInfoArg.DmIndexInfoCriteria;
import com.ztesoft.web.common.db.dao.DmDataCommandDao;
import com.ztesoft.web.common.db.dao.DmIndexInfoDao;
import com.ztesoft.web.common.db.dao.DmProcedureDao;
import com.ztesoft.web.common.db.po.DmDataCommandPO;
import com.ztesoft.web.common.db.po.DmIndexInfoPO;
import com.ztesoft.web.common.db.po.DmProcedurePO;
import com.ztesoft.web.resourcecheck.IdxCheck;
import com.ztesoft.web.resourcecheck.LModeCheck;
import com.ztesoft.web.syncbaseinfo.service.BaseInfoService;

/**
 * <Description> <br>
 * 
 * @author lin.jie<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2015年8月20日 <br>
 * @since V1.0<br>
 * @see com.ztesoft.web.baseconfig.service.impl <br>
 */

@Service("dmSrcTableService")
public class DmSrcTableServiceImpl implements IDmSrcTableService {

	private static final ZTEsoftLogManager logger = ZTEsoftLogManager.getLogger(DmSrcTableServiceImpl.class);

	@Autowired
	private DmSrcTableDao dmSrcTableDao;
	@Autowired
	private DmPlanDao dmPlanDao;

	@Autowired
	private IDmPlanService dmPlanService;
	@Autowired
	private IDmPlanRelationService dmPlanRelationService;
	@Autowired
	private IDmStrategyService dmStrategyService;
	@Autowired
	private IDmStrategyDataobjRelService dmStrategyDataobjRelService;
	@Autowired
	private ISubTableDefineService subTableDefineService;
	@Autowired
	private DmPlanRelationDao dmPlanRelationDao;
	@Autowired
	private DmStrategyDao dmStrategyDao;
	@Autowired
	private DmStrategyDataobjRelDao dmStrategyDataobjRelDao;
	@Autowired
	private SubTableDefineDao subTableDefineDao;
	@Autowired
	private DmTableRelDao dmTableRelDao;
	@Autowired
	private IDmTableRelService dmTableRelService;
	@Autowired
	private BaseInfoService baseInfoService;
	@Autowired
	private DynamicDataSourceManager dynamicDataSourceManager;
	@Autowired
	private DmDataCommandDao dmDataCommandDao;
	@Autowired
	private DmProcedureDao dmProcedureDao;

	@Autowired
	private DmIndexInfoDao dmIndexInfoDao;
	
	@Autowired
	private IdxCheck idxCheck;
	@Autowired
	private LModeCheck lModeCheck;

	/**
	 * 查询条件转换成Arg类的服务接口
	 */
	@Resource(name = "defaultArgConversionService")
	private IArgConversionService argConversionService;

	/**
	 * 主键生成器
	 */
	@Resource(name = "sequenceProcGenerator")
	private ISequenceGenerator sequenceGenerator;

	@Override
	public DmSrcTablePO selectByPrimaryKey(Integer key) throws BaseAppException {
		return dmSrcTableDao.selectByPrimaryKey(key);
	}

	@Override
	public List<DmSrcTablePO> selectByTableName(DmSrcTablePO record) throws BaseAppException {
		DmSrcTableArg arg = new DmSrcTableArg();
		DmSrcTableCriteria criteria = arg.createCriteria();
		criteria.andTableNameEqualTo(record.getTableName());
		criteria.andDbLinkIdEqualTo(record.getDbLinkId());
		criteria.andDbUserNameEqualTo(record.getDbUserName());// 判断源表是否配置过，增加DbUserName字段
		criteria.andStateNotEqualTo(Status.CANCELLED.toString());
		List<DmSrcTablePO> dstPOList = dmSrcTableDao.selectByArg(arg);
		// 排除已经失效的策略的表
		/*
		 * for (int i = 0; i < dstPOList.size(); i++) { DmPlanRelationPO dprPO =
		 * dmPlanRelationService
		 * .selectBySourceDataId(dstPOList.get(i).getSourceDataId()); if
		 * (Utils.notEmpty(dprPO)) {// 说明该表的计划已经失效 dstPOList.remove(i); i--; } }
		 */
		return dstPOList;
	}

	@Override
	public DmSrcTablePO selectByTableNameForShow(DmSrcTablePO record) throws BaseAppException {
		DmSrcTableArg dstArg = new DmSrcTableArg();
		DmSrcTableCriteria dstcCriteria = dstArg.createCriteria();
		dstcCriteria.andTableNameEqualTo(record.getTableName());
		dstcCriteria.andDbLinkIdEqualTo(record.getDbLinkId());
		dstcCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
		DmSrcTablePO dstPO = dmSrcTableDao.selectByArg(dstArg).get(0);

		DmStrategyDataobjRelArg dsdrArg = new DmStrategyDataobjRelArg();
		DmStrategyDataobjRelCriteria dsdrcCriteria = dsdrArg.createCriteria();
		dsdrcCriteria.andSourceDataIdEqualTo(dstPO.getSourceDataId());
		dsdrcCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
		List<DmStrategyDataobjRelPO> dsdrPOList = dmStrategyDataobjRelDao.selectByArg(dsdrArg);
		if (dsdrPOList.size() != 0) {// 该源表正在被使用
			dstPO.setSourceDataId(-1);
			return dstPO;
		}
		// 获取策略信息
		// DmStrategyArg dsArg = new DmStrategyArg();
		// DmStrategyCriteria dsCriteria = dsArg.createCriteria();
		// dsCriteria.andDmStrategyIdEqualTo(dsdrPOList.get(0).getDmStrategyId());
		// dsCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
		// List<DmStrategyPO> dsPOList = dmStrategyDao.selectByArg(dsArg);
		// if (dsPOList.size() != 0) {
		// dstPO.setHotDataFlag(dsPOList.get(0).getHotDataFlag());
		// dstPO.setUpperCnt(dsPOList.get(0).getUpperCnt());
		// dstPO.setConcurrentNumber(dsPOList.get(0).getConcurrentNumber());
		// dstPO.setBatchCommitCount(dsPOList.get(0).getBatchCommitCount());
		// }
		// 分表定义
		SubTableDefinePO stdPO_1 = new SubTableDefinePO();
		stdPO_1.setSourceDataId(dstPO.getSourceDataId());
		stdPO_1.setDataType(1);
		dstPO.setTableNameArray(subTableDefineService.selectBySourceDataIdForSrc(dstPO.getTableName(), stdPO_1)
				.toArray(new TableNamePO[0]));
		// 从表
		List<DmSrcTablePO> subDstList = dmSrcTableDao.selectSubTableBySourceDataId(dstPO.getSourceDataId());
		List<SubTablePO> subTables = new ArrayList<SubTablePO>();
		if (subDstList.size() != 0) {
			for (DmSrcTablePO po : subDstList) {
				SubTablePO stPO = new SubTablePO();
				stPO.setSourceDataId(po.getSourceDataId());
				stPO.setDbLinkId(po.getDbLinkId());
				stPO.setSubDbUserName(po.getDbUserName());
				SubTableDefinePO stdPO_2 = new SubTableDefinePO();
				stdPO_2.setSourceDataId(po.getSourceDataId());
				stdPO_2.setDataType(1);
				stPO.setSubTableNames(subTableDefineService
						.selectBySourceDataIdForSubAndTgt(po.getTableName(), stdPO_2).toArray(new TableNamePO[0]));
				DmTableRelPO dtrPO = dmTableRelService.selectByPrimaryKey(po.getSourceDataId());
				// 字段关系
				stPO.setRelMapCols(dtrPO.getRelMapCols());
				stPO.setSubMapCols(dtrPO.getSubMapCols());
				stPO.setAllColumns(selectAllColumns(po.getDbLinkId(), po.getDbUserName(), po.getTableName()));
				subTables.add(stPO);
			}
		}
		dstPO.setSubTables(subTables);
		dstPO.setAllColumns(selectAllColumns(dstPO.getDbLinkId(), dstPO.getDbUserName(), dstPO.getTableName()));
		
		String tableName = dstPO.getTableName().toLowerCase();
		// 表索引，锁模式，检测
		String[] dbConfig = baseInfoService.getDbConfig(dstPO.getDbLinkId(), dstPO.getDbUserName());
		dstPO.setDbType(dbConfig[0]);
		// 表索引
		if (dbConfig[0].equals("oracle")) {// oracle
			tableName = tableName.toUpperCase();
		}
		List<DmIndexInfoPO> diiPOList = idxCheck.qryIdxForPO(dstPO.getDbLinkId(), tableName, dbConfig);
		dstPO.setDiiPOList(diiPOList);
		// 锁模式
		String lMode = "";
		if (dbConfig[0].equals("informix")) {// informix
			lMode = lModeCheck.qryIfxLMode(dstPO.getDbLinkId(), tableName, dbConfig);
		}
		dstPO.setLockMode(lMode);
		return dstPO;
	}

	@Override
	public List<DmSrcTablePO> searchTableNameForSelect(String term) throws BaseAppException {
		// 查询出所有不等于00X的源表
		DmSrcTableArg dstArg = new DmSrcTableArg();
		DmSrcTableCriteria dstCriteria = dstArg.createCriteria();
		dstCriteria.andTableNameLike(term.trim());
		dstCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
		List<DmSrcTablePO> dstPOList = dmSrcTableDao.selectByArg(dstArg);
		// 过滤正在被使用的源表、所有分表
		for (int i = 0; i < dstPOList.size(); i++) {
			if (dstPOList.get(i).getMainDataId() != null) {
				dstPOList.remove(i);
				i--;
				continue;
			}
			DmStrategyDataobjRelArg dsdrArg = new DmStrategyDataobjRelArg();
			DmStrategyDataobjRelCriteria dsdrcCriteria = dsdrArg.createCriteria();
			dsdrcCriteria.andSourceDataIdEqualTo(dstPOList.get(i).getSourceDataId());
			dsdrcCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
			if (dmStrategyDataobjRelDao.selectByArg(dsdrArg).size() != 0) {// 该源表正在被使用
				dstPOList.remove(i);
				i--;
				continue;
			}
		}
		return dstPOList;
	}

	@Override
	public List<DmSrcTablePO> selectByArg(DmSrcTablePO record) throws BaseAppException {
		logger.debug("selectByArg begin...record={0}", record);
		DmSrcTableArg arg = argConversionService.invokeArg(DmSrcTableArg.class, record);
		return dmSrcTableDao.selectByArg(arg);
	}

	@Override
	public List<DmSrcTablePO> selectSubTableBySourceDataId(Integer id) throws BaseAppException {
		return dmSrcTableDao.selectSubTableBySourceDataId(id);
	}

	@Override
	public Page<DmSrcTablePO> selectByArgAndPage(DmSrcTablePO record, Page<DmSrcTablePO> resultPage)
			throws BaseAppException {
		logger.debug("selectByArgAndPage begin...record={0}", record);
		DmSrcTableArg arg = argConversionService.invokeArg(DmSrcTableArg.class, record);
		resultPage = dmSrcTableDao.selectByArgAndPage(arg, resultPage);
		return resultPage;
	}

	/**
	 * 验证表名是否存在，返回字段
	 */
	@Override
	public ColumnNamePO[] selectTableName(DmSrcTablePO record, boolean isSubTable, boolean hasSubTable, boolean isRead)
			throws BaseAppException {
		List<ColumnNamePO> resultList = new ArrayList<ColumnNamePO>();
		String tableName = "";
		if (isSubTable) {
			TableNamePO[] tableNames = record.getSubTableNameArray();
			tableName = tableNames[0].getValue();
		} else {
			if (hasSubTable) {
				TableNamePO[] tableNames = record.getTableNameArray();
				tableName = tableNames[0].getValue();
			} else {
				tableName = record.getTableName();
			}
		}
		if (!isRead && Utils.notEmpty(dmSrcTableDao.selectByTableName(tableName))) {
			ColumnNamePO po = new ColumnNamePO();
			po.setValue("1");
			po.setColumnName("2");
			resultList.add(po);
		} else {
			return selectAllColumns(record.getDbLinkId(), record.getDbUserName(), tableName);
		}
		return resultList.toArray(new ColumnNamePO[0]);
	}

	@Override
	public DmSrcTablePO add(DmSrcTablePO record) throws Exception {
		logger.debug("添加源表数据={0}", record);
		/*
		 * 替换，数据库必填，前台空值，的字段的值 所有非空字段： 不需要替换： 需要替换：
		 */
		if (Utils.isEmpty(record.getTableName())) {
			record.setTableName(DMSConstant.DRAFT_STRING_REPLACE);
		}
		if (Utils.isEmpty(record.getLowerOffset())) {
			record.setLowerOffset(DMSConstant.DRAFT_SHORT_NUMBER_REPLACE);
		}
		Date nowDate = new Date();
		record.setStateDate(nowDate);
		// 通过前台传回来的ID，从数据库里找，是否已经有这条数据了
		DmSrcTablePO dstPO = dmSrcTableDao.selectByPrimaryKey(record.getSourceDataId());
		if (Utils.isEmpty(dstPO)) {// 不存在这条记录，说明是新增
			// 查找是否存在相同的表
			DmSrcTableArg arg = new DmSrcTableArg();
			DmSrcTableCriteria criteria = arg.createCriteria();
			criteria.andTableNameEqualTo(record.getTableName());
			if (Utils.notEmpty(record.getDbLinkId())) {
				criteria.andDbLinkIdEqualTo(record.getDbLinkId());
			}
			criteria.andDbUserNameEqualTo(record.getDbUserName());// 判断表是否配置过，增加DbUserName字段
			criteria.andStateNotEqualTo(Status.CANCELLED.toString());
			List<DmSrcTablePO> dstPOList = dmSrcTableDao.selectByArg(arg);
			if (dstPOList.size() != 0) {// 存在相同表名的记录，不可以保存
				record.setDmStrategyId(0);
			} else {
				record.setCreateDate(nowDate);
				dmSrcTableDao.insertSelective(record);
				// 新增源表后，添加表索引记录
				if (Utils.notEmpty(record.getDiiPOList()) && record.getDiiPOList().size() != 0) {
					for (DmIndexInfoPO diiPO : record.getDiiPOList()) {
						int indexInfoId = sequenceGenerator.sequenceIntValue("DM_INDEX_INFO", "INDEX_INFO_ID");
						diiPO.setIndexInfoId(indexInfoId);
						diiPO.setSeqNbr(1);
						diiPO.setDataId(record.getSourceDataId());
						diiPO.setState(Status.SUCCESS.toString());
						diiPO.setStateDate(nowDate);
						diiPO.setCreateDate(nowDate);
						dmIndexInfoDao.insertSelective(diiPO);
					}
				}
			}
		} else {// 修改
			if (dstPO.getState().equals(Status.DRAFT.toString())) {// 草稿箱，点击提交
				// 草稿箱状态为00D或者0DA，直接修改草稿箱，状态改为00A
				dmSrcTableDao.updateByPrimaryKeySelective(record);
			} else {// 修改，点击提交
				// 先把原来的记录状态改成00X
				dstPO.setState(Status.CANCELLED.toString());
				dstPO.setStateDate(nowDate);
				dmSrcTableDao.updateByPrimaryKeySelective(dstPO);
				// 再新增一条序号为 +1 的记录
				record.setSeqNbr(dstPO.getSeqNbr() + 1);
				record.setCreateDate(dstPO.getCreateDate());
				dmSrcTableDao.insertSelective(record);
			}
			// 修改表索引记录
			DmIndexInfoArg diiArg = new DmIndexInfoArg();
			DmIndexInfoCriteria diiCriteria = diiArg.createCriteria();
			diiCriteria.andDataIdEqualTo(record.getSourceDataId());
			diiCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
			List<DmIndexInfoPO> diiPOList = dmIndexInfoDao.selectByArg(diiArg);
			if (diiPOList.size() != 0) {
				// 之前的序号
				Integer seqNbr = diiPOList.get(0).getSeqNbr();
				for (DmIndexInfoPO diiPO : diiPOList) {
					// 先把原来的记录状态改成00X
					diiPO.setState(Status.CANCELLED.toString());
					diiPO.setStateDate(nowDate);
					dmIndexInfoDao.updateByPrimaryKeySelective(diiPO);
				}
				// 新增新的表索引，序号为 +1 的记录
				List<DmIndexInfoPO> diiPOList_new = record.getDiiPOList();
				for (DmIndexInfoPO diiPO : diiPOList_new) {
					int indexInfoId = sequenceGenerator.sequenceIntValue("DM_INDEX_INFO", "INDEX_INFO_ID");
					diiPO.setIndexInfoId(indexInfoId);
					diiPO.setSeqNbr(seqNbr + 1);
					diiPO.setDataId(record.getSourceDataId());
					diiPO.setState(Status.SUCCESS.toString());
					diiPO.setStateDate(nowDate);
					diiPO.setCreateDate(nowDate);
					dmIndexInfoDao.insertSelective(diiPO);
				}
			}
		}
		return record;
	}

	@Override
	public int update(DmSrcTablePO record) throws BaseAppException {
		logger.debug("update begin...record={0}", record);
		return dmSrcTableDao.updateByPrimaryKeySelective(record);
	}

	@Override
	public int delete(DmSrcTablePO record) throws BaseAppException {
		logger.debug("delete begin...record={0}", record);
		int staffId = record.getStaffId();
		record = dmSrcTableDao.selectByPrimaryKey(record.getSourceDataId());
		dmSrcTableDao.updateTo00X(record.getSourceDataId());
		record.setStaffId(staffId);
		record.setSeqNbr(record.getSeqNbr() + 1);
		record.setState(Status.CANCELLED.toString());
		record.setStateDate(new Date());
		return dmSrcTableDao.insertSelective(record);
	}

	@Override
	public DmSrcTablePO selectByDmStrategyId(DmStrategyPO dsPO) throws Exception {
		DmSrcTablePO dstPO = dmSrcTableDao.selectBydmStrategyId(dsPO.getDmStrategyId());
		dstPO.setHotDataFlag(dsPO.getHotDataFlag());
		dstPO.setUpperCnt(dsPO.getUpperCnt() / 10000);
		dstPO.setConcurrentNumber(dsPO.getConcurrentNumber());
		dstPO.setBatchCommitCount(dsPO.getBatchCommitCount());
		// 分表定义
		SubTableDefinePO stdPO_1 = new SubTableDefinePO();
		stdPO_1.setSourceDataId(dstPO.getSourceDataId());
		stdPO_1.setDataType(1);
		dstPO.setTableNameArray(subTableDefineService.selectBySourceDataIdForSrc(dstPO.getTableName(), stdPO_1)
				.toArray(new TableNamePO[0]));
		// 从表
		List<DmSrcTablePO> subDstList = dmSrcTableDao.selectSubTableBySourceDataId(dstPO.getSourceDataId());
		List<SubTablePO> subTables = new ArrayList<SubTablePO>();
		if (subDstList.size() != 0) {
			for (DmSrcTablePO po : subDstList) {
				SubTablePO stPO = new SubTablePO();
				stPO.setSourceDataId(po.getSourceDataId());
				stPO.setDbLinkId(po.getDbLinkId());
				stPO.setSubDbUserName(po.getDbUserName());
				SubTableDefinePO stdPO_2 = new SubTableDefinePO();
				stdPO_2.setSourceDataId(po.getSourceDataId());
				stdPO_2.setDataType(1);
				stPO.setSubTableNames(subTableDefineService
						.selectBySourceDataIdForSubAndTgt(po.getTableName(), stdPO_2).toArray(new TableNamePO[0]));
				DmTableRelPO dtrPO = dmTableRelService.selectByPrimaryKey(po.getSourceDataId());
				// 字段关系
				stPO.setRelMapCols(dtrPO.getRelMapCols());
				stPO.setSubMapCols(dtrPO.getSubMapCols());
				stPO.setAllColumns(selectAllColumns(po.getDbLinkId(), po.getDbUserName(), po.getTableName()));
				// 表索引
				DmIndexInfoArg diiArg = new DmIndexInfoArg();
				DmIndexInfoCriteria diiCriteria = diiArg.createCriteria();
				diiCriteria.andDataIdEqualTo(stPO.getSourceDataId());
				diiCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
				List<DmIndexInfoPO> diiPOList = dmIndexInfoDao.selectByArg(diiArg);
				stPO.setDiiPOList(diiPOList);
				subTables.add(stPO);
			}
		}
		dstPO.setSubTables(subTables);
		List<DmDataCommandPO> commandList = dmDataCommandDao.selectBySrcDataId(dstPO.getSourceDataId());
		DmProcedurePO dmProcedurePO = dmProcedureDao.selectBySourceDataId(dstPO.getSourceDataId());
		if (dstPO.getArchiveMode() == 2) {
			if (commandList != null && commandList.size() == 2) {
				for (DmDataCommandPO dmDataCommandPO : commandList) {
					if (dmDataCommandPO.getCommandType() == 0) {
						// 导出
						dstPO.setExportTableArea(getSubString(dmDataCommandPO.getCommand(), "@", "file="));
						dstPO.setExportCommandArea(getSubString(dmDataCommandPO.getCommand(), "file=", "tables"));
					} else {
						dstPO.setImportTableArea(getSubString(dmDataCommandPO.getCommand(), "@", "file="));
						dstPO.setImportCommandArea(getSubString(dmDataCommandPO.getCommand(), "file=", "full=y"));
						// 导入
					}
				}
			}
		} else if (dstPO.getArchiveMode() == 3) {
			if (commandList != null && commandList.size() == 2) {
				for (DmDataCommandPO dmDataCommandPO : commandList) {
					if (dmDataCommandPO.getCommandType() == 0) {
						// 导出
						dstPO.setExportTable(getSubString(dmDataCommandPO.getCommand(), "@", "file="));
						dstPO.setExportCommand(getSubString(dmDataCommandPO.getCommand(), "file=", "tables"));
					} else {
						// 导入
						dstPO.setImportTable(getSubString(dmDataCommandPO.getCommand(), "@", "full=y"));
						dstPO.setImportCommand(getSubString(dmDataCommandPO.getCommand(), "file=", "ignore=y"));
					}
				}
			}
			if (dmProcedurePO != null) {
				dstPO.setProcedureName(dmProcedurePO.getProcedureName());
			}
		}
		dstPO.setAllColumns(selectAllColumns(dstPO.getDbLinkId(), dstPO.getDbUserName(), dstPO.getTableName()));
		
		// dstPO.setKeyColumn(selectPkColumns(dstPO.getDbLinkId(),
		// dstPO.getDbUserName(), dstPO.getTableName()));
		
		// 表索引
		DmIndexInfoArg diiArg = new DmIndexInfoArg();
		DmIndexInfoCriteria diiCriteria = diiArg.createCriteria();
		diiCriteria.andDataIdEqualTo(dstPO.getSourceDataId());
		diiCriteria.andStateNotEqualTo(Status.CANCELLED.toString());
		List<DmIndexInfoPO> diiPOList = dmIndexInfoDao.selectByArg(diiArg);
		dstPO.setDiiPOList(diiPOList);
		return dstPO;
	}

	private String getSubString(String Command, String beginStr, String endStr) {
		String resStr = "";
		if (!"".equals(Command)) {
			resStr = Command.substring(Command.indexOf(beginStr) + beginStr.length(), Command.indexOf(endStr));
		}
		resStr.trim();
		return resStr;
	}

	@Override
	public DmSrcTablePO selectBydmStrategyId(Integer dmStrategyId) throws BaseAppException {
		return dmSrcTableDao.selectBydmStrategyId(dmStrategyId);
	}

	// 根据Form表单里的条件返回dmPlanId

	// 根据Form表单里的条件返回dmPlanId,草稿箱

	@Override
	public List<DmSrcTablePO> selectByArgFormDraft(DmSrcTablePO record) throws BaseAppException {
		List<DmSrcTablePO> resultList = dmSrcTableDao.selectByArgFormDraft(record);
		return resultList;
	}

	// 根据Form表单里的条件返回dmPlanId,计划维护
	@Override
	public List<DmSrcTablePO> selectByArgFormMaint(DmSrcTablePO record) throws BaseAppException {

		// DmSrcTableArg arg = new DmSrcTableArg();
		// DmSrcTableCriteria criteria = arg.createCriteria();
		// if (Utils.notEmpty(record.getDbLinkId())) { //数据库
		// criteria.andDbLinkIdEqualTo(record.getDbLinkId());
		// }
		// if (Utils.notEmpty(record.getDbUserName())) { //用户名
		// criteria.andDbUserNameLike(record.getDbUserName());
		// }
		// if (Utils.notEmpty(record.getTableName())) { //表名
		// criteria.andTableNameLike(record.getTableName());
		// }
		// List<DmSrcTablePO> resultList =
		// dmSrcTableDao.selectByArgForm(record);

		// DmSrcTableArg arg = new DmSrcTableArg();
		// DmSrcTableCriteria criteria = arg.createCriteria();
		// if (Utils.notEmpty(record.getDbLinkId())) { //数据库
		// criteria.andDbLinkIdEqualTo(record.getDbLinkId());
		// }
		// if (Utils.notEmpty(record.getDbUserName())) { //用户名
		// criteria.andDbUserNameLike(record.getDbUserName());
		// }
		// if (Utils.notEmpty(record.getTableName())) { //表名
		// criteria.andTableNameLike(record.getTableName());
		// }
		List<DmSrcTablePO> resultList = dmSrcTableDao.selectByArgFormMaint(record);

		return resultList;
	}

	@Override
	public int getRecordSize(Integer dbLinkId, String dbUserName, String tableName) throws BaseAppException {
		if (Utils.isEmpty(dbLinkId) || Utils.isEmpty(dbUserName)) {
			return 0;
		}
		String[] dbConfig = null;
		DataSource ds = null;
		dbConfig = baseInfoService.getDbConfig(dbLinkId, dbUserName);
		ds = dynamicDataSourceManager.getDruidDataSource(dbLinkId + dbUserName, dbConfig);
		Connection con = DataSourceUtils.getConnection(ds);
		String sql = "select * from " + tableName + " where 1=0";
		int count = 0;
		try {
			DatabaseMetaData meta = con.getMetaData();
			ResultSet columns = con.createStatement().executeQuery(sql);
			ResultSetMetaData rsmd = columns.getMetaData();
			for (int i = 1; i <= rsmd.getColumnCount(); i++) {
				count += rsmd.getColumnDisplaySize(i);
			}
		} catch (SQLException e1) {
			e1.printStackTrace();
		} finally {
			try {
				DataSourceUtils.doReleaseConnection(con, ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return count;
	}

	@Override
	public String selectPkColumns(Integer dbBaseId, String dbUserName, String tableName) throws BaseAppException,
			Exception {
		String pkColumns = "";
		if (Utils.isEmpty(dbBaseId) || Utils.isEmpty(dbUserName)) {
			return pkColumns;
		}
		DataSource ds = null;
		Connection con = null;
		try {
			String[] dbConfig = null;
			dbConfig = baseInfoService.getDbConfig(dbBaseId, dbUserName);
			// 针对oracle关键字段显示的修改
			if (Utils.notEmpty(dbConfig) && "oracle".equalsIgnoreCase(dbConfig[0])) {
				tableName = tableName.toUpperCase();
			}
			ds = dynamicDataSourceManager.getDruidDataSource(dbBaseId + dbUserName, dbConfig);
			con = DataSourceUtils.getConnection(ds);
			DatabaseMetaData meta = con.getMetaData();
			ResultSet columns = meta.getPrimaryKeys(null, null, tableName.trim());
			while (columns.next()) {
				pkColumns = pkColumns + columns.getString("COLUMN_NAME").toLowerCase() + ",";
			}
			return pkColumns.substring(0, pkColumns.length() - 1);
		} catch (Exception e) {
			return pkColumns;
		} finally {
			try {
				DataSourceUtils.doReleaseConnection(con, ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public ColumnNamePO[] selectAllColumns(Integer dbBaseId, String dbUserName, String tableName)
			throws BaseAppException {
		List<ColumnNamePO> resultList = new ArrayList<ColumnNamePO>();
		if (Utils.isEmpty(dbBaseId) || Utils.isEmpty(dbUserName)) {
			return resultList.toArray(new ColumnNamePO[0]);
		}
		DataSource ds = null;
		Connection con = null;
		try {
			String[] dbConfig = null;
			dbConfig = baseInfoService.getDbConfig(dbBaseId, dbUserName);
			ds = dynamicDataSourceManager.getDruidDataSource(dbBaseId + dbUserName, dbConfig);
			// 原始方法
			// JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
			// String sql =
			// "select DISTINCT column_name, data_type from information_schema.columns WHERE table_name = '"
			// + tableName + "'";
			// List<Map<String, Object>> retList =
			// jdbcTemplate.queryForList(sql);
			// for (Map<String, Object> entityMap : retList) {
			// ColumnNamePO po = new ColumnNamePO();
			// po.setValue(entityMap.get("column_name").toString());
			// po.setColumnName(entityMap.get("column_name").toString());
			// po.setDataType(1);
			// resultList.add(po);
			// }
			// 修改方法
			logger.debug(Thread.currentThread() + "获取连接中...");
			con = DataSourceUtils.getConnection(ds);
			logger.debug(Thread.currentThread() + "获取链接信息ok");
			String sql = "select * from " + tableName + " where 1=0";
			ResultSet columns = con.createStatement().executeQuery(sql);
			ResultSetMetaData rsmd = columns.getMetaData();
			for (int i = 1; i <= rsmd.getColumnCount(); i++) {
				ColumnNamePO po = new ColumnNamePO();
				po.setValue(rsmd.getColumnName(i).toLowerCase());
				po.setColumnName(rsmd.getColumnName(i).toLowerCase());
				po.setDataType(Util.uniteColumnType(rsmd.getColumnType(i)));
				po.setColumnSize(rsmd.getColumnDisplaySize(i));
				po.setNullable(rsmd.isNullable(i));
				resultList.add(po);
			}
		} catch (Exception e) {
			e.printStackTrace();
			ColumnNamePO po = new ColumnNamePO();
			po.setValue("-2");
			po.setColumnName("-2");
			resultList.add(po);
		} finally {
			try {
				DataSourceUtils.doReleaseConnection(con, ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return resultList.toArray(new ColumnNamePO[0]);
	}

	@Override
	public String scriptVerify(DmTargetTablePO dttPO, DmSrcTablePO dstPO) throws BaseAppException {
		dstPO.setTableNameArray(JsonUtil.toArray(dstPO.getTableName(), TableNamePO.class));
		String resultSql = null;
		String sql = "";
		DataSource ds = null;
		Connection con = null;
		try {
			String[] dbConfig = null;
			dbConfig = baseInfoService.getDbConfig(dstPO.getDbLinkId(), dstPO.getDbUserName());
			ds = dynamicDataSourceManager.getDruidDataSource(dstPO.getDbLinkId() + dstPO.getDbUserName(), dbConfig);
			con = DataSourceUtils.getConnection(ds);
			JdbcTemplate jdbcTemplate = new JdbcTemplate(ds);
			String tableName = "";
			TableNamePO[] tableNames = dstPO.getTableNameArray();
			tableName = tableNames[0].getValue().trim();
			resultSql = "select * from " + tableName;
			sql = resultSql;
			if (Utils.isEmpty(dstPO.getSelectCondition())) {
				sql = sql + " where 1 = 2";
			} else {
				sql = sql + " where " + dstPO.getSelectCondition() + " and 1 = 2";
			}
			jdbcTemplate.queryForList(sql);
			sql = sql.replaceAll(" where 1 = 2", "");
			sql = sql.replaceAll(" and 1 = 2", "");
			return 0 + sql;
		} catch (Exception e) {
			e.printStackTrace();
			String resultException = e.toString();
			resultException = resultException.replaceAll(" where 1 = 2", "");
			resultException = resultException.replaceAll(" and 1 = 2", "");
			sql = sql.replaceAll(" where 1 = 2", "");
			sql = sql.replaceAll(" and 1 = 2", "");
			sql = sql + "\n" + resultException;
			return 1 + sql;
		} finally {
			try {
				DataSourceUtils.doReleaseConnection(con, ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}

	@Override
	public Map<String, Integer> findDataType(Integer dbBaseId, String dbUserName, String tableName)
			throws BaseAppException, Exception {
		Map<String, Integer> map = new HashMap<String, Integer>();
		DataSource ds = null;
		Connection con = null;
		try {
			String[] dbConfig = null;
			dbConfig = baseInfoService.getDbConfig(dbBaseId, dbUserName);
			ds = dynamicDataSourceManager.getDruidDataSource(dbBaseId + dbUserName, dbConfig);
			con = DataSourceUtils.getConnection(ds);
			String sql = "select * from " + tableName + " where 1=0";
			ResultSet columns = con.createStatement().executeQuery(sql);
			ResultSetMetaData rsmd = columns.getMetaData();
			for (int i = 1; i <= rsmd.getColumnCount(); i++) {
				map.put(rsmd.getColumnName(i).toLowerCase(), rsmd.getColumnType(i));
			}
		} catch (Exception e) {

		} finally {
			try {
				DataSourceUtils.doReleaseConnection(con, ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return map;
	}

	@Override
	public List<DmSrcTablePO> findProcedureInfo(Integer dbBaseId, String dbUserName) throws BaseAppException, Exception {
		String sql = "";
		int dbloop = 1;
		List<DmSrcTablePO> poList = new ArrayList<DmSrcTablePO>();
		Map<String, Integer> map = new HashMap<String, Integer>();
		DataSource ds = null;
		Connection con = null;
		DmSrcTablePO po = null;
		try {
			String[] dbConfig = null;
			dbConfig = baseInfoService.getDbConfig(dbBaseId, dbUserName);
			ds = dynamicDataSourceManager.getDruidDataSource(dbBaseId + dbUserName, dbConfig);
			con = DataSourceUtils.getConnection(ds);
			if ("oracle".equals(dbConfig[0])) {
				sql = "select object_name, object_id from user_objects where object_type='PROCEDURE' ";
			}
			if ("informix".equals(dbConfig[0])) {
				sql = "select * from SYSPROCEDURES ";
			}
			if ("mysql".equals(dbConfig[0])) {
				sql = "select name,db from mysql.proc ";
			}
			ResultSet columns = con.createStatement().executeQuery(sql);
			int index = 0;
			while (columns.next()) {
				dbloop = 1;
				po = new DmSrcTablePO();
				// po.setProcedureId(columns.getString(dbloop++));
				po.setProcedureName(columns.getString(dbloop++));
				poList.add(po);
				index++;
			}
		} catch (Exception e) {
			logger.debug(e);
		} finally {
			try {
				DataSourceUtils.doReleaseConnection(con, ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		return poList;
	}

	@Override
	public Map<String, String> qryInfoByDbLinkId(Integer dbBaseId, String dbUserName, String tableName)
			throws BaseAppException, Exception {
		String sql = "0";
		String res = "0";
		Map<String, String> resMap = new HashMap<String, String>();
		String areaStr = "";
		int dbloop = 1;
		List<DmSrcTablePO> poList = new ArrayList<DmSrcTablePO>();
		Map<String, Integer> map = new HashMap<String, Integer>();
		DataSource ds = null;
		Connection con = null;
		DmSrcTablePO po = null;
		try {
			String[] dbConfig = null;
			dbConfig = baseInfoService.getDbConfig(dbBaseId, dbUserName);
			ds = dynamicDataSourceManager.getDruidDataSource(dbBaseId + dbUserName, dbConfig);
			con = DataSourceUtils.getConnection(ds);
			if ("oracle".equals(dbConfig[0])) {
				res = "1";
				sql = "SELECT * FROM USER_TAB_PARTITIONS where table_name = '" + tableName + "'";
			}

			ResultSet columns = con.createStatement().executeQuery(sql);
			int index = 0;
			while (columns.next()) {
				dbloop = 1;
				areaStr = "1";
				index++;
			}
		} catch (Exception e) {
			logger.debug(e);
		} finally {
			try {
				DataSourceUtils.doReleaseConnection(con, ds);
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		resMap.put("oracle", res);
		resMap.put("area", areaStr);
		return resMap;
	}
}
